package cz.data.auth.service;

import cz.data.common.core.DataConstant;
import cz.data.common.core.DataRole;
import cz.data.common.core.DataUser;
import cz.data.domain.system.model.vo.PostVo;
import cz.data.domain.system.model.vo.RoleVo;
import cz.data.domain.system.model.vo.UserInfo;
import cz.data.domain.system.model.vo.UserVo;
import cz.data.domain.system.rpc.UserServiceFeign;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.*;
import java.util.stream.Collectors;

public class DataUserDetailService implements UserDetailsService {

    @Autowired
    private UserServiceFeign userServiceFeign;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        // 远程获取用户
        UserInfo userInfo = userServiceFeign.loginByUsername(s);

        if (userInfo == null) {
            throw new UsernameNotFoundException(String.format("%s用户不存在", s));
        }
        // 可用性 :true:可用 false:不可用
        boolean enabled = true;
        // 过期性 :true:没过期 false:过期
        boolean accountNonExpired = true;
        // 有效性 :true:凭证有效 false:凭证无效
        boolean credentialsNonExpired = true;
        // 锁定性 :true:未锁定 false:已锁定
        boolean accountNonLocked = true;
        Set<String> authsSet = new HashSet<>();
        if (Objects.nonNull(userInfo.getPerms())
                && userInfo.getPerms().length > 0) {
            authsSet.addAll(Arrays.asList(userInfo.getPerms()));
        }
        UserVo userVo = userInfo.getUserVo();
        List<RoleVo> roles = userVo.getRoles();
        if (CollectionUtils.isNotEmpty(roles)) {
            roles.stream()
                    .filter(roleVo -> StringUtils.isNotBlank(roleVo.getRoleCode()))
                    .forEach(roleVo -> authsSet.add(DataConstant.Security.ROLEPREFIX.getVal() + roleVo.getRoleCode()));
        }
        if (CollectionUtils.isEmpty(authsSet)) {
            authsSet.add(DataConstant.Security.ROLEPREFIX.getVal() + "VISITOR");
        }
        Collection<? extends GrantedAuthority> authorities
                = AuthorityUtils.createAuthorityList(authsSet.toArray(new String[0]));
        DataUser user = new DataUser(userVo.getId(), userVo.getNickname(), userVo.getUsername(), userVo.getPassword(),
                enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        if (StringUtils.isNotBlank(userVo.getDeptId())) {
            user.setDept(userVo.getDeptId());
        }
        if (CollectionUtils.isNotEmpty(userVo.getPosts())) {
            user.setPosts(userVo.getPosts().stream().map(PostVo::getId).collect(Collectors.toList()));
        }

        if (CollectionUtils.isNotEmpty(userVo.getRoles())) {
            user.setRoles(userVo.getRoles().stream().map(roleVo -> {
                DataRole dataRole = new DataRole();
                dataRole.setId(roleVo.getId());
                dataRole.setDataScope(roleVo.getDataScope());
                return dataRole;
            }).collect(Collectors.toList()));
        }
        return user;
    }
}
